/**
 * 
 */
package sourceFiles;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;

import Exceptions.*;
import Exceptions.CentralComputerExceptions.ErrorInGuardianPassword;
import Exceptions.CentralComputerExceptions.GuardianIDDoesntExist;
import Exceptions.CentralComputerExceptions.InvalidPassword;
import sourceFiles.IApplication;
import sourceFiles.GuardianEntry;

/**
 * @author LASO-Team
 * 
 */
public class CentralComputer implements ICentralComputer {

	private XMLRidesParser parser;
	private HashMap<Integer, Integer> ticketsSold;
	private SupervisorStation supervisorStation;
	private LinkedList<GuardianEntry> guardiansList;
	private LinkedList<ChildEntry> childrenList;
	private LinkedList<IRide> ridesList;
	private LinkedList<RideEntry> ridesCatalog;
	// private LinkedList<IApplication> applicationList;
	private IApplication application;

	/*--------------------------------------------------------------------------*/
	public CentralComputer(String path) throws XMLRidesParserException {
		parser = new XMLRidesParser(path);
		ticketsSold = new HashMap<Integer, Integer>();
		supervisorStation = new SupervisorStation(this);
		guardiansList = new LinkedList<GuardianEntry>();
		childrenList = new LinkedList<ChildEntry>();
		ridesList = new LinkedList<IRide>();
		ridesCatalog = new LinkedList<RideEntry>();
		application = new Application(this);

	}

	// public HashMap<Integer, Integer> getTicketsSold() {
	// return ticketsSold;
	// }
	//
	// public void setTicketsSold(HashMap<Integer, Integer> ticketsSold) {
	// this.ticketsSold = ticketsSold;
	// }
	//
	// public SupervisorStation getSupervisorStation() {
	// return supervisorStation;
	// }
	//
	// public void setSupervisorStation(SupervisorStation supervisorStation) {
	// this.supervisorStation = supervisorStation;
	// }
	//
	// public LinkedList<GuardianEntry> getGuardiansList() {
	// return guardiansList;
	// }
	//
	// public void setGuardiansList(LinkedList<GuardianEntry> guardiansList) {
	// this.guardiansList = guardiansList;
	// }
	//
	// public LinkedList<ChildEntry> getChildrenList() {
	// return childrenList;
	// }
	//
	// public void setChildrenList(LinkedList<ChildEntry> childrenList) {
	// this.childrenList = childrenList;
	// }
	//
	 public LinkedList<IRide> getRidesList() {
	 return ridesList;
	 }
	//
	// public void setRidesList(LinkedList<IRide> ridesList) {
	// this.ridesList = ridesList;
	// }
	//
	public LinkedList<RideEntry> getRidesCatalog() {
		return ridesCatalog;
	}

	//
	// public void setRidesCatalog(LinkedList<RideEntry> ridesCatalog) {
	// this.ridesCatalog = ridesCatalog;
	// }

	// public LinkedList<IApplication> getApplicationList() {
	// return applicationList;
	// }
	//
	// public void setApplicationList(LinkedList<IApplication> applicationList)
	// {
	// this.applicationList = applicationList;
	// }

	/*--------------------------------------------------------------------------*/

	/**
	 * @param ride
	 * @param child
	 * @return
	 */
	private Boolean areChildParamsValid(IRide ride, ChildEntry child) {
		// TODO add implementation!
		return null;
	}

	/**
	 * @param rideID
	 * @param childID
	 */
	private void UpdateCurrentLocationOfChild(Integer rideID, Integer childID) {
		// TODO add implementation!
	}

	/**
	 * @param rideID
	 */
	private void addToTicketsSold(Integer rideID) {
		// TODO add implementation!
	}

	/**
	 * @param rideID
	 */
	private void removeFromTicketsSold(Integer rideID) {
		// TODO add implementation!
	}

	/*--------------------------------------------------------------------------*/

	@Override
	public void createRide(String rideName, Boolean isExtremeRide,
			Integer maxCapacity, Integer minAge, Integer minHeight)
			throws InvalidRideName, InvalidCapacity, InvalidAgeParam,
			InvalidHeightParam {
		// params testing
		if (rideName == null) {
			throw new InvalidRideName();
		}
		checkRideParams(maxCapacity, minAge, minHeight);

		Integer newRideID = generateNewRideId();

		// add new RideEntry
		Double newRidePrice = genrateNewRidePrice();
		RideEntry newRideEntry;
		if (isExtremeRide) {
			newRideEntry = new ExtremeRideEntry(rideName, newRideID,
					newRidePrice);
		} else {
			newRideEntry = new RegularRideEntry(rideName, newRideID,
					newRidePrice);
		}
		ridesCatalog.add(newRideEntry);

		// add new Ride
		ridesList.add(new Ride(newRideID, maxCapacity, minAge, minHeight,
				rideName, RideState.STANDBY, this));
		// TODO: define how to apply runRideCycle

	}

	@Override
	public void updateRide(Integer rideID, Integer maxCapacity, Integer minAge,
			Integer minHeight) throws InvalidRideId, InvalidCapacity,
			InvalidAgeParam, InvalidHeightParam {
//		if (rideID < 1) {
//			throw new InvalidRideId();
//		}
//		checkRideParams(maxCapacity, minAge, minHeight);
//		// TODO: when can a ride be updated? if a ride is holding kids at the
//		// moment, can it be updated?
//		// TODO: need getters and setters for changing the state of the ride
//		// while still using an interface
	}

	@Override
	public void addGuardian(Integer guardianID, Integer billingInfo) {
		// TODO Auto-generated method stub
		// TODO GUI is using this method, save it for later

	}

	@Override
	public void addChildToGuardian(Integer guardianID, Integer childID,
			Integer age, Integer height) {
		// TODO Auto-generated method stub
		// TODO GUI is using this method, save it for later
	}

	@Override
	public void connectGuardian(Integer userID, String userPassword)
			throws InvalidPersonID, InvalidPassword, GuardianIDDoesntExist,
			ErrorInGuardianPassword {
		if (userID < 1) {
			throw new InvalidPersonID();
		}
		if (userPassword == null) {
			throw new InvalidPassword();
		}
		GuardianEntry guardian = null;
		for (GuardianEntry g : guardiansList) {
			if (g == null) {
				continue;
			}
			if (g.getID() == userID) {
				guardian = g;
				break;
			}
		}
		if (guardian == null) {
			throw new ErrorInGuardianPassword(); // guardian was not found
		}
		if (guardian.getPassword() != userPassword) {
			throw new ErrorInGuardianPassword(); // guardian was found but
													// password doesn't match
		}

	}

	@Override
	public void buyingProcess(Integer rideID, Integer guardianID,
			Integer childID) {
		// TODO Auto-generated method stub

	}

	@Override
	public void performBilling(Double ridePrice, Integer billingInfo) {
		// TODO Auto-generated method stub

	}

	@Override
	public void cancelAcquisition(Integer rideID, Integer guardianID,
			Integer childID) {
		// TODO Auto-generated method stub

	}

	@Override
	public void validateChildForRide(Integer rideID, Integer childID) {
		// TODO Auto-generated method stub

	}

	@Override
	public Map<Integer, Integer> retrieveChildrenLocation(Integer guardianID) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ETicket retrieveChildETicket(Integer childID) {
		// TODO Auto-generated method stub
		return null;
	}

	private void checkRideParams(Integer maxCapacity, Integer minAge,
			Integer minHeight) throws InvalidCapacity, InvalidAgeParam,
			InvalidHeightParam {
		if (maxCapacity < 1) {
			throw new InvalidCapacity();
		}
		if (minAge < 1) {
			throw new InvalidAgeParam();
		}
		if (minHeight < 1) {
			throw new InvalidHeightParam();
		}
	}

	private Integer generateNewRideId() {
		return ridesList.size() + 1;
	}

	private Double genrateNewRidePrice() {
		Random rand = new Random();

		return rand.nextDouble() * 10.0;
	}

	@Override
	public void childLeavesRide(Integer childID) {
		// TODO Auto-generated method stub
		
	}
}
